/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package at.alexanderpehm.pony;

import at.alexanderpehm.pony.controller.NoteBookDAO;
import at.alexanderpehm.pony.model.NoteInfo;
import at.alexanderpehm.pony.event.EventRegistry;
import java.awt.Toolkit;
import java.io.File;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionListener;

public class NoteTree implements TreeSelectionListener {

    protected DefaultMutableTreeNode rootNode;
    protected DefaultTreeModel treeModel;
    protected JTree tree;
    private NoteInfo currentlySelectedNote;
    private NoteBookDAO noteDAO = new NoteBookDAO();

    public JTree getTree() {
        return tree;
    }
    private Toolkit toolkit = Toolkit.getDefaultToolkit();

    public NoteTree(String path) {
        if (path == null) {
            rootNode = new DefaultMutableTreeNode("Root Node");
        }
        rootNode = initTreeNodes(path);
        treeModel = new DefaultTreeModel(rootNode);
        treeModel.addTreeModelListener(new MyTreeModelListener());
        tree = new JTree(treeModel);
        tree.setEditable(true);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.addTreeSelectionListener(this);
        tree.setShowsRootHandles(true);
    }

    /** Remove all nodes except the root node. */
    public void clear() {
        rootNode.removeAllChildren();
        treeModel.reload();
    }

    /** Remove the currently selected node. */
    public void removeCurrentNode() {
        TreePath currentSelection = tree.getSelectionPath();
        if (currentSelection != null) {
            DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelection.getLastPathComponent());
            MutableTreeNode parent = (MutableTreeNode) (currentNode.getParent());
            if (parent != null) {
                treeModel.removeNodeFromParent(currentNode);
                return;
            }
        }

        // Either there was no selection, or the root was selected.
        toolkit.beep();
    }

    /** Add child to the currently selected node. */
    public DefaultMutableTreeNode addObject(Object child) {
        DefaultMutableTreeNode parentNode = null;
        TreePath parentPath = tree.getSelectionPath();

        if (parentPath == null) {
            parentNode = rootNode;
        } else {
            parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent());
        }

        return addObject(parentNode, child, true);
    }

    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
            Object child) {
        return addObject(parent, child, false);
    }

    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
            Object child,
            boolean shouldBeVisible) {
        DefaultMutableTreeNode childNode =
                new DefaultMutableTreeNode(child);

        if (parent == null) {
            parent = rootNode;
        }

        //It is key to invoke this on the TreeModel, and NOT DefaultMutableTreeNode
        treeModel.insertNodeInto(childNode, parent,
                parent.getChildCount());

        //Make sure the user can see the lovely new node.
        if (shouldBeVisible) {
            tree.scrollPathToVisible(new TreePath(childNode.getPath()));
        }
        return childNode;
    }

    private DefaultMutableTreeNode initTreeNodes(String path) {
        System.out.println(path);
        File notesDir = new File(path);
        String[] directories = notesDir.list();
        NoteInfo noteInfo = new NoteInfo(notesDir.getName(), "");
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(noteInfo);
        for (String noteName : directories) {
            NoteInfo nodeNoteInfo = new NoteInfo(noteName, noteName);
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(nodeNoteInfo);
            root.add(node);
        }
        return root;
    }

    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        if (node == null) {
            return;
        }
        Object nodeObj = node.getUserObject();
        if (node.isLeaf()) {
            NoteInfo noteInfo = (NoteInfo) nodeObj;
            this.currentlySelectedNote = noteInfo;
            EventRegistry.getInstance().notifyListeners(EventRegistry.EventType.NOTE_SELECTED, noteInfo);
    }
}

    void clearAndLoadNew() {
        rootNode.removeAllChildren();
        rootNode = initTreeNodes(NoteBookDAO.getCurrentNotebookPath());
        treeModel.setRoot(rootNode);
    }

class MyTreeModelListener implements TreeModelListener {

    public void treeNodesChanged(TreeModelEvent e) {
        DefaultMutableTreeNode node;
        node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent());

        /*
         * If the event lists children, then the changed
         * node is the child of the node we've already
         * gotten.  Otherwise, the changed node and the
         * specified node are the same.
         */

        int index = e.getChildIndices()[0];
        node = (DefaultMutableTreeNode) (node.getChildAt(index));
        System.out.println("old val: " + currentlySelectedNote.getRelativePath());
        System.out.println("The user has finished editing the node.");
        System.out.println("New value: " + node.getUserObject());
        NoteInfo renameResult = noteDAO.renameNote(currentlySelectedNote, node.getUserObject().toString());
        if(renameResult!=null){
            node.setUserObject(renameResult);
        }
    }

    public void treeNodesInserted(TreeModelEvent e) {
    }

    public void treeNodesRemoved(TreeModelEvent e) {
    }

    public void treeStructureChanged(TreeModelEvent e) {
    }
}
}

